#include "encoder.h"
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"

/**
  * @brief	      重映射配置，专门为AT32芯片包 + STM32BSP设计
  * @param	      无
  * @retval       无
  * @author       718 Lab
  */
static void AT32_TIM2_TIM3_Remap(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//开重映射时钟
    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //shut JTAG
    GPIO_PinRemapConfig(GPIO_FullRemap_TIM2,ENABLE);
}

/**
  * @brief	      编码器初始化
  * @param	      无
  * @retval       无
  * @author       718 Lab
  */
void Encoder_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

	E_P_RCC_APBxPeriphClockCmd1(E_P_RCC_APBPeriph_TIMx_GPIOx1, ENABLE);
    E_P_RCC_APBxPeriphClockCmd2(E_P_RCC_APBPeriph_TIMx_GPIOx2, ENABLE);
    E_P_RCC_APBxPeriphClockCmd3(E_P_RCC_APBPeriph_TIMx_GPIOx3, ENABLE);
    E_P_RCC_APBxPeriphClockCmd4(E_P_RCC_APBPeriph_TIMx_GPIOx4, ENABLE);

    AT32_TIM2_TIM3_Remap();

    GPIO_InitStructure.GPIO_Pin =  ENCODER1_TIM_CH1_PIN | ENCODER1_TIM_CH2_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
    GPIO_Init(ENCODER1_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin =  ENCODER2_TIM_CH1_PIN | ENCODER2_TIM_CH2_PIN|ENCODER3_TIM_CH2_PIN;
    GPIO_Init(ENCODER2_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin =  ENCODER3_TIM_CH1_PIN;
    GPIO_Init(ENCODER3_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin =  ENCODER4_TIM_CH1_PIN | ENCODER4_TIM_CH2_PIN;
    GPIO_Init(ENCODER4_PORT, &GPIO_InitStructure);

    E_RCC_APBxPeriphClockCmd1(E_RCC_APBPeriph_TIMx1,ENABLE);
    E_RCC_APBxPeriphClockCmd2(E_RCC_APBPeriph_TIMx2,ENABLE);
    E_RCC_APBxPeriphClockCmd3(E_RCC_APBPeriph_TIMx3,ENABLE);
    E_RCC_APBxPeriphClockCmd4(E_RCC_APBPeriph_TIMx4,ENABLE);

/*--------------------时基结构体初始化-------------------------*/
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	// 自动重装载寄存器的值，累计TIM_Period+1个频率后产生一个更新或者中断
	TIM_TimeBaseStructure.TIM_Period=65535;	
	// 驱动CNT计数器的时钟 = Fck_int/(psc+1)
	TIM_TimeBaseStructure.TIM_Prescaler= 0;	
	// 时钟分频因子 ，配置死区时间时需要用到
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;				
	// 重复计数器的值，没用到不用管
	TIM_TimeBaseStructure.TIM_RepetitionCounter=0;	
	// 初始化定时器
	TIM_TimeBaseInit(ENCODER1_TIM, &TIM_TimeBaseStructure);
    TIM_TimeBaseInit(ENCODER2_TIM, &TIM_TimeBaseStructure);
    TIM_TimeBaseInit(ENCODER3_TIM, &TIM_TimeBaseStructure);
    TIM_TimeBaseInit(ENCODER4_TIM, &TIM_TimeBaseStructure);

	/*--------------------输入捕获结构体初始化-------------------*/	
  // 使用PWM输入模式时，需要占用两个捕获寄存器，一个测周期，另外一个测占空比
	
	TIM_ICInitTypeDef  TIM_ICInitStructure;
	// 捕获通道IC1配置
	// 选择捕获通道
    //TIM_ICInitStructure.TIM_Channel = catch_TIM_IC1PWM_CHANNEL;
	// 设置捕获的边沿
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
	// 设置捕获通道的信号来自于哪个输入通道，有直连和非直连两种
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
	// 1分频，即捕获信号的每个有效边沿都捕获
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	// 不滤波
    TIM_ICInitStructure.TIM_ICFilter = 0x0;

	// 初始化
	TIM_EncoderInterfaceConfig(ENCODER1_TIM, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
    //编码器模式开启，上升沿触发
    TIM_ICInit(ENCODER1_TIM, &TIM_ICInitStructure);

    TIM_EncoderInterfaceConfig(ENCODER2_TIM, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
    //编码器模式开启，上升沿触发
    TIM_ICInit(ENCODER2_TIM, &TIM_ICInitStructure);

    TIM_EncoderInterfaceConfig(ENCODER3_TIM, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
    //编码器模式开启，上升沿触发
    TIM_ICInit(ENCODER3_TIM, &TIM_ICInitStructure);

    TIM_EncoderInterfaceConfig(ENCODER4_TIM, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
    //编码器模式开启，上升沿触发
    TIM_ICInit(ENCODER4_TIM, &TIM_ICInitStructure);
	
	// 使能高级控制定时器，计数器开始计数
    TIM_Cmd(ENCODER1_TIM, ENABLE);
    TIM_Cmd(ENCODER2_TIM, ENABLE);
    TIM_Cmd(ENCODER3_TIM, ENABLE);
    TIM_Cmd(ENCODER4_TIM, ENABLE);
}

/**
  * @brief	      读取编码器的值
  * @param	      ENCODER_TIM,可以输入ENCODER1_TIM,ENCODER2_TIM,ENCODER3_TIM,ENCODER4_TIM,读取对应编码器的值
  * @retval       无
  * @author       718 Lab
  */
int read_encoder (TIM_TypeDef* ENCODER_TIM)
{
    if(ENCODER_TIM!=ENCODER1_TIM&&ENCODER_TIM!=ENCODER2_TIM&&ENCODER_TIM!=ENCODER3_TIM&&ENCODER_TIM!=ENCODER4_TIM)
    return 0;//确保是设计的时钟
    int temp=(int16_t)(ENCODER_TIM->CNT);
    ENCODER_TIM->CNT=0;
    return temp;
}

